<?php

require_once 'vendor/autoload.php';

use Smalot\Cups\Builder\Builder;
use Smalot\Cups\Manager\JobManager;
use Smalot\Cups\Manager\PrinterManager;
use Smalot\Cups\Model\Job;
use Smalot\Cups\Model\Printer;
use Smalot\Cups\Transport\Client;
use Smalot\Cups\Transport\ResponseParser;
use Http\Client\Socket\Client as HttpClient;

/**
 * EPSON L4260 Series 最终打印测试
 * IP: 10.1.0.12
 * 
 * 此脚本提供多种打印方式的完整测试
 */

echo "🖨️  EPSON L4260 Series 最终打印测试\n";
echo "打印机IP: 10.1.0.12\n";
echo str_repeat('=', 60) . "\n\n";

// 测试选项
echo "请选择测试方式:\n";
echo "1. IPP网络打印 (推荐)\n";
echo "2. Windows系统打印 (备用)\n";
echo "3. 网络连接诊断\n";
echo "4. 全部测试\n";
echo "\n请输入选择 (1-4): ";

$choice = trim(fgets(STDIN));

switch ($choice) {
    case '1':
        testIPPPrint();
        break;
    case '2':
        testWindowsPrint();
        break;
    case '3':
        testNetworkDiagnostics();
        break;
    case '4':
        testAll();
        break;
    default:
        echo "无效选择，执行全部测试...\n\n";
        testAll();
        break;
}

echo "\n" . str_repeat('=', 60) . "\n";
echo "测试完成！\n";

/**
 * 测试IPP网络打印
 */
function testIPPPrint() {
    echo "\n🌐 IPP网络打印测试\n";
    echo str_repeat('-', 40) . "\n";
    
    try {
        // 1. 初始化组件
        echo "1. 初始化CUPS-IPP组件...\n";
        $builder = new Builder();
        $httpClient = new HttpClient();
        $responseParser = new ResponseParser();
        
        $printerManager = new PrinterManager($builder, $httpClient, $responseParser);
        $jobManager = new JobManager($builder, $httpClient, $responseParser);
        echo "✓ 组件初始化完成\n\n";
        
        // 2. 测试打印机连接
        echo "2. 测试打印机连接...\n";
        $printerUri = 'ipp://10.1.0.12:631/ipp/print';
        
        // 尝试查找打印机
        try {
            $printer = $printerManager->findByUri($printerUri);
            if ($printer) {
                echo "✓ 找到打印机: " . $printer->getName() . "\n";
            } else {
                echo "⚠️  未找到打印机，创建新的打印机对象\n";
                $printer = new Printer();
                $printer->setUri($printerUri);
                $printer->setName('EPSON L4260 Series');
            }
        } catch (Exception $e) {
            echo "⚠️  查找打印机失败，创建新的打印机对象\n";
            $printer = new Printer();
            $printer->setUri($printerUri);
            $printer->setName('EPSON L4260 Series');
        }
        
        echo "  - 打印机URI: " . $printer->getUri() . "\n";
        echo "  - 打印机名称: " . $printer->getName() . "\n\n";
        
        // 3. 创建打印任务
        echo "3. 创建打印任务...\n";
        $job = new Job();
        $job->setName('EPSON L4260 IPP测试');
        $job->setUsername('ipp-test');
        $job->setCopies(1);
        
        // 添加打印内容
        $content = createTestContent('IPP');
        $job->addText($content);
        
        echo "✓ 打印任务创建完成\n";
        echo "  - 任务名称: " . $job->getName() . "\n";
        echo "  - 用户名: " . $job->getUsername() . "\n\n";
        
        // 4. 发送打印任务
        echo "4. 发送IPP打印任务...\n";
        echo "正在连接到 10.1.0.12:631...\n";
        
        $result = $jobManager->send($printer, $job);
        
        if ($result) {
            echo "\n🎉 IPP打印任务发送成功！\n";
            echo "请检查打印机输出...\n";
        } else {
            echo "\n❌ IPP打印任务发送失败\n";
            echo "尝试备用方案...\n";
            testWindowsPrint();
        }
        
    } catch (Exception $e) {
        echo "\n❌ IPP打印失败\n";
        echo "错误: " . $e->getMessage() . "\n";
        echo "\n尝试备用方案...\n";
        testWindowsPrint();
    }
}

/**
 * 测试Windows系统打印
 */
function testWindowsPrint() {
    echo "\n🖥️  Windows系统打印测试\n";
    echo str_repeat('-', 40) . "\n";
    
    if (PHP_OS_FAMILY !== 'Windows') {
        echo "❌ 当前系统不是Windows，跳过此测试\n";
        return;
    }
    
    // 创建测试文件
    $testFile = 'epson_windows_test.txt';
    $content = createTestContent('Windows');
    
    file_put_contents($testFile, $content);
    echo "✓ 测试文件创建完成: $testFile\n";
    
    // 尝试不同的打印机名称
    $printerNames = [
        'EPSON L4260 Series',
        'EPSON L4260',
        'L4260 Series',
        'EPSONBD5110' // 从网络诊断中发现的名称
    ];
    
    $success = false;
    
    foreach ($printerNames as $printerName) {
        echo "\n尝试打印机名称: $printerName\n";
        
        $command = "print /D:\"$printerName\" \"$testFile\"";
        echo "执行命令: $command\n";
        
        $output = [];
        $returnCode = 0;
        exec($command . ' 2>&1', $output, $returnCode);
        
        if ($returnCode === 0) {
            echo "✅ Windows打印成功！\n";
            echo "打印机: $printerName\n";
            $success = true;
            break;
        } else {
            echo "❌ 失败: " . implode(' ', $output) . "\n";
        }
    }
    
    if (!$success) {
        echo "\n❌ 所有Windows打印尝试都失败\n";
        echo "\n💡 建议:\n";
        echo "1. 检查打印机是否已安装并设为默认\n";
        echo "2. 在控制面板中验证打印机名称\n";
        echo "3. 尝试从记事本等应用程序打印测试页\n";
        
        // 列出系统中的打印机
        listSystemPrinters();
    }
    
    // 清理测试文件
    if (file_exists($testFile)) {
        unlink($testFile);
        echo "\n✓ 测试文件已清理\n";
    }
}

/**
 * 网络连接诊断
 */
function testNetworkDiagnostics() {
    echo "\n🔍 网络连接诊断\n";
    echo str_repeat('-', 40) . "\n";
    
    $ip = '10.1.0.12';
    
    // 1. Ping测试
    echo "1. Ping测试...\n";
    $pingCommand = "ping -n 4 $ip";
    echo "执行: $pingCommand\n";
    
    $output = [];
    exec($pingCommand, $output);
    
    $pingSuccess = false;
    foreach ($output as $line) {
        if (strpos($line, 'TTL=') !== false) {
            $pingSuccess = true;
            echo "✓ Ping成功: $line\n";
            break;
        }
    }
    
    if (!$pingSuccess) {
        echo "❌ Ping失败\n";
        foreach ($output as $line) {
            echo "  $line\n";
        }
        return;
    }
    
    // 2. 端口测试
    echo "\n2. IPP端口631测试...\n";
    $connection = @fsockopen($ip, 631, $errno, $errstr, 5);
    
    if ($connection) {
        echo "✓ 端口631连接成功\n";
        fclose($connection);
    } else {
        echo "❌ 端口631连接失败: $errstr ($errno)\n";
    }
    
    // 3. HTTP端口80测试
    echo "\n3. HTTP端口80测试...\n";
    $connection = @fsockopen($ip, 80, $errno, $errstr, 5);
    
    if ($connection) {
        echo "✓ 端口80连接成功\n";
        fclose($connection);
        
        // 尝试获取打印机网页
        echo "\n4. 尝试访问打印机网页...\n";
        $url = "http://$ip/";
        $context = stream_context_create([
            'http' => [
                'timeout' => 5,
                'method' => 'GET'
            ]
        ]);
        
        $response = @file_get_contents($url, false, $context);
        if ($response) {
            echo "✓ 打印机网页访问成功\n";
            echo "  URL: $url\n";
            
            // 检查是否包含EPSON相关信息
            if (stripos($response, 'epson') !== false) {
                echo "✓ 确认为EPSON打印机\n";
            }
        } else {
            echo "❌ 打印机网页访问失败\n";
        }
    } else {
        echo "❌ 端口80连接失败: $errstr ($errno)\n";
    }
    
    // 5. 路由追踪
    echo "\n5. 路由追踪...\n";
    $traceCommand = "tracert -h 5 $ip";
    echo "执行: $traceCommand\n";
    
    $output = [];
    exec($traceCommand, $output);
    
    foreach ($output as $line) {
        if (trim($line)) {
            echo "  $line\n";
        }
    }
}

/**
 * 列出系统打印机
 */
function listSystemPrinters() {
    echo "\n📋 系统打印机列表\n";
    echo str_repeat('-', 30) . "\n";
    
    // 使用PowerShell获取打印机列表
    $command = 'powershell "Get-Printer | Select-Object Name, DriverName, PortName | Format-Table -AutoSize"';
    
    $output = [];
    exec($command, $output);
    
    if (!empty($output)) {
        foreach ($output as $line) {
            if (trim($line)) {
                echo "$line\n";
            }
        }
    } else {
        echo "❌ 无法获取打印机列表\n";
    }
}

/**
 * 执行全部测试
 */
function testAll() {
    echo "\n🔄 执行全部测试\n";
    echo str_repeat('=', 60) . "\n";
    
    testNetworkDiagnostics();
    testIPPPrint();
    testWindowsPrint();
    
    echo "\n📊 测试总结\n";
    echo str_repeat('-', 30) . "\n";
    echo "✓ 网络诊断完成\n";
    echo "✓ IPP打印测试完成\n";
    echo "✓ Windows打印测试完成\n";
    echo "\n💡 建议: 如果IPP打印失败，可以使用Windows系统打印作为备用方案\n";
}

/**
 * 创建测试内容
 */
function createTestContent($method) {
    $content = "";
    $content .= str_repeat('=', 50) . "\n";
    $content .= "      EPSON L4260 Series 打印测试\n";
    $content .= "         方式: $method\n";
    $content .= str_repeat('=', 50) . "\n\n";
    
    $content .= "测试信息:\n";
    $content .= "- 时间: " . date('Y-m-d H:i:s') . "\n";
    $content .= "- IP地址: 10.1.0.12\n";
    $content .= "- 打印方式: $method\n";
    $content .= "- PHP版本: " . PHP_VERSION . "\n";
    $content .= "- 系统: " . PHP_OS . "\n\n";
    
    $content .= "功能验证:\n";
    $content .= "✓ 网络连接正常\n";
    $content .= "✓ 打印机响应\n";
    $content .= "✓ 任务创建成功\n";
    $content .= "✓ 内容传输完成\n";
    $content .= "✓ 中文字符: 爱普生打印机测试成功\n\n";
    
    $content .= "字符测试:\n";
    $content .= "英文: ABCDEFGHIJKLMNOPQRSTUVWXYZ\n";
    $content .= "数字: 0123456789\n";
    $content .= "符号: !@#$%^&*()_+-=[]{}|\\:;\"'<>?,./ \n\n";
    
    $content .= "如果您能清楚地看到这个测试页面，\n";
    $content .= "说明EPSON L4260打印功能正常工作！\n\n";
    
    $content .= str_repeat('-', 50) . "\n";
    $content .= "测试完成时间: " . date('Y-m-d H:i:s') . "\n";
    $content .= "测试ID: " . uniqid() . "\n";
    
    return $content;
}